package com.mxpio.erp.purchase.controller;

import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.inventory.entity.WarehouseOrderLine;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.purchase.entity.AcceptanceOrder;
import com.mxpio.erp.common.purchase.entity.PurchaseOrder;
import com.mxpio.erp.common.purchase.entity.PurchaseOrderLine;
import com.mxpio.erp.common.purchase.service.AcceptanceOrderService;
import com.mxpio.erp.common.purchase.service.PurchaseOrderLineService;
import com.mxpio.erp.common.purchase.service.PurchaseOrderService;
import com.mxpio.erp.common.service.OrderService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.CriteriaUtils;
import com.mxpioframework.jpa.query.Operator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

@Api(value = "PurchaseOrderController", tags = { "采购订单数据接口" })
@RestController
@RequestMapping("/erp/purc/po/")
public class PurchaseOrderController {

    @Autowired
    private PurchaseOrderService purchaseOrderService;

    @Autowired
    private PurchaseOrderLineService purchaseOrderLineService;

    @Autowired
    private AcceptanceOrderService acceptanceOrderService;
    
    @Autowired
    private OrderService orderService;

    @GetMapping("list")
    @ApiOperation(value = "采购订单列表", notes = "获取采购订单（无分页）", httpMethod = "GET")
    public Result<List<PurchaseOrder>> list(String criteria) throws UnsupportedEncodingException {
        Criteria c = CriteriaUtils.json2Criteria(criteria);
        List<PurchaseOrder> purchaseOrders = purchaseOrderService.list(PurchaseOrder.class, c);
        return Result.OK(purchaseOrders);
    }

    @GetMapping("page")
    @ApiOperation(value = "采购订单列表", notes = "获取采购订单（分页）", httpMethod = "GET")
    public Result<Page<PurchaseOrder>> page(String criteria, Integer pageSize, Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo - 1, pageSize);
        Criteria c = CriteriaUtils.json2Criteria(criteria);
        Page<PurchaseOrder> purchaseOrders = purchaseOrderService.listPage(PurchaseOrder.class, page, c);
        return Result.OK(purchaseOrders);
    }

    @GetMapping("list/{bizNo}")
    @ApiOperation(value = "根据bizNo获取采购订单", notes = "根据bizNo获取采购订单", httpMethod = "GET")
    public Result<PurchaseOrder> getById(@PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder purchaseOrder = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        return Result.OK(purchaseOrder);
    }

    @PostMapping("add")
    @ApiOperation(value = "新增采购订单", notes = "新增采购订单", httpMethod = "POST")
    public Result<PurchaseOrder> add(@RequestBody PurchaseOrder purchaseOrder) {
        purchaseOrderService.save(purchaseOrder);
        return Result.OK(purchaseOrder);
    }

    @PostMapping("save")
    @ApiOperation(value = "保存采购订单", notes = "保存采购订单")
    public Result<PurchaseOrder> save(@RequestBody PurchaseOrder purchaseOrder) {
        purchaseOrderService.save(purchaseOrder,new SmartCrudPolicyAdapter(){
        	@Override
        	public boolean beforeInsert(CrudContext context) {
        		Object o = context.getEntity();
        		if(o instanceof PurchaseOrderLine){
        			PurchaseOrder purchaseOrder = context.getParent();
                    ((PurchaseOrderLine) o).setBizNo(purchaseOrder.getBizNo());
        		}
        		return true;
        	}
        });
        return Result.OK(purchaseOrder);
    }
    
    @PutMapping("edit")
    @ApiOperation(value = "编辑采购订单", notes = "编辑采购订单", httpMethod = "PUT")
    public Result<PurchaseOrder> edit(@RequestBody PurchaseOrder purchaseOrder) {
        purchaseOrderService.update(purchaseOrder);
        return Result.OK(purchaseOrder);
    }

    @DeleteMapping("remove/{bizNo}")
    @ApiOperation(value = "根据bizNo删除采购订单", notes = "根据bizNo删除采购订单,多个bizNo用英文逗号分隔", httpMethod = "DELETE")
    public Result<PurchaseOrder> remove(@PathVariable(name = "bizNo", required = true) String bizNos) {
        String[] bizNo = bizNos.split(",");
        for (String key : bizNo) {
            Criteria c = Criteria.create().addCriterion("bizNo", Operator.EQ, key);
            purchaseOrderLineService.removeBatch(PurchaseOrderLine.class, c);
            purchaseOrderService.remove(PurchaseOrder.class, key);
        }
        return Result.OK();
    }

    @PutMapping("open/{bizNo}")
    @ApiOperation(value = "打开采购订单", notes = "打开采购订单", httpMethod = "PUT")
    public Result<? extends Order> open(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder po = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        return orderService.updateCloseStatus(po, OrderStatusEnums.CloseStatus.OPEN);
    }

    @PutMapping("close/{bizNo}")
    @ApiOperation(value = "关闭采购订单", notes = "关闭采购订单", httpMethod = "PUT")
    public Result<? extends Order> close(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder po = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        return orderService.updateCloseStatus(po, OrderStatusEnums.CloseStatus.CLOSED);
    }

    @PutMapping("submit/{bizNo}")
    @ApiOperation(value = "提交采购订单", notes = "提交采购订单", httpMethod = "PUT")
    public Result<? extends Order> submit(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder po = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        if (po.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode())) {
            return orderService.updateBpmnStatus(po, OrderStatusEnums.BpmnStatus.AUDITING);
        } else {
            return Result.error("非开立状态不可提交");
        }
    }

    @PutMapping("audit/{bizNo}")
    @ApiOperation(value = "审核采购订单", notes = "审核采购订单", httpMethod = "PUT")
    public Result<? extends Order> audit(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder po = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        if (po.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())) {
            return orderService.updateBpmnStatus(po, OrderStatusEnums.BpmnStatus.AUDITED);
        } else {
            return Result.error("非审核中状态不可审核");
        }
    }

    @PutMapping("abandon/{bizNo}")
    @ApiOperation(value = "弃审采购订单", notes = "弃审采购订单", httpMethod = "PUT")
    public Result<? extends Order> abandon(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        PurchaseOrder po = purchaseOrderService.getById(PurchaseOrder.class, bizNo);
        if (po.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode()) || po.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())) {
            return orderService.updateBpmnStatus(po, OrderStatusEnums.BpmnStatus.CREATE);
        } else {
            return Result.error("非审核中、已审核状态不可审核");
        }
    }

    @GetMapping("ao/{bizNo}")
    @ApiOperation(value = "反查验收单列表", notes = "反查验收单列表", httpMethod = "GET")
    public Result<List<AcceptanceOrder>> listAo(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
        Criteria c = Criteria.create();
        c.addCriterion("purchaseBizNo", Operator.EQ, bizNo);
        List<AcceptanceOrder> AcceptanceOrders = acceptanceOrderService.list(AcceptanceOrder.class, c);
        return Result.OK(AcceptanceOrders);
    }

    @GetMapping("wo/{bizNo}")
    @ApiOperation(value = "反查入库单列表", notes = "反查入库单列表", httpMethod = "GET")
    public Result<List<WarehouseOrderLine>> listwo(@ApiParam(name = "业务单号") @PathVariable(name = "bizNo", required = true) String bizNo) {
       //TODO: 入库单尚未开发
        List<WarehouseOrderLine> WarehouseOrderLines = new ArrayList<>();
        return Result.OK(WarehouseOrderLines);
    }
}


